From: Keir Fraser Date: Mon, 20 Oct 2008 14:31:54 +0000 (+0100) Subject: vmx: avoid taking locks with irqs disabled X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14066^2~19 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=8e75cae72a33c531e2ca39adf834fcad8fca2307;p=xen.git vmx: avoid taking locks with irqs disabled Shuffle the bits of the vmexit handler that run with EFLAGS.IF == 0 up to the top. Otherwise we end up calling spin_lock() with interrupts disabled, which can deadlock against the time-synchronization rendezvous code. Signed-off-by: Tim Deegan --- diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 407b677899..ed99ec8073 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2056,8 +2056,12 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) perfc_incra(vmexits, exit_reason); - if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT ) - local_irq_enable(); + /* Handle the interrupt we missed before allowing any more in. */ + if ( exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT ) + vmx_do_extint(regs); + + /* Now enable interrupts so it's safe to take locks. */ + local_irq_enable(); if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) ) return vmx_failed_vmentry(exit_reason, regs); @@ -2185,7 +2189,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) break; } case EXIT_REASON_EXTERNAL_INTERRUPT: - vmx_do_extint(regs); + /* Already handled above. */ break; case EXIT_REASON_TRIPLE_FAULT: hvm_triple_fault();